import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Modal, Tooltip, Radio, message } from 'antd';
import { addOneday, getAllStrategies, getAllHasPocOnedayList } from '@api/task';
import _ from 'lodash';
import moment from 'moment';
import './index.less';
import TaskCommonFields from '@components/task-common-fields';
import { connect } from 'react-redux';
import isClusterModel from '@components/is-cluster-model';
const prefixCls = 'custom-oneday-modal';
const RadioGroup = Radio.Group;

class CustomOnedayModal extends Component {
  constructor(props) {
    super(props);
    this.defaultState = {
      enableWhiteList: false,
      runAt: {
        isRunAt: false,
        time: moment().format('YYYY-MM-DD HH:mm')
      },
      strategy: this.props.strategy || 'template',
      checkedTemplate: {},
      selectedOnedays: [],
      selectedOnedaysError: '',
      ignoreIpsError: '',
      ignoreType: {
        whitelist: false,
        custom: false
      },
      customIgnoreTarget: [],
      timing: {},
      startAt: '',
      endAt: '',
      errorMsg: '',
      priority: 'middle'
    };
    this.state = {
      ...this.defaultState,
      templates: [],
      onedays: []
    };
  }

  componentDidMount() {
    this.loadAllStrategyTemplates();
    this.loadOnedays();
  }

  componentDidUpdate(prevProps) {
    if (this.props.strategy && this.props.strategy !== prevProps.strategy) {
      this.setState({ strategy: this.props.strategy });
    }
  }

  loadAllStrategyTemplates = () => {
    getAllStrategies().then(res => {
      const templates = _.get(res, 'data.data.list', []);
      this.setState({ templates });
    });
  };

  loadOnedays = () => {
    getAllHasPocOnedayList().then(res => {
      const onedays = _.get(res, 'data.data.list', []);
      this.setState({ onedays });
    });
  };

  onChangeTemplate = checkedTemplate => {
    this.setState({ checkedTemplate, selectedOnedaysError: '' });
  };

  onStrategyChange = e => {
    const strategy = e.target.value;
    this.setState({ strategy, selectedOnedaysError: '' }, () => {
      if (strategy === 'template') {
        this.loadAllStrategyTemplates();
      }
    });
  };

  onSelectOnedays = keys => {
    let error = '';
    if (!keys.length) {
      error = '插件选择不能为空';
    }
    this.setState({
      selectedOnedays: keys,
      selectedOnedaysError: error
    });
  };

  onSubmit = async () => {
    const { isCluster } = this.props;
    // 如果是集群设备但是没有节点
    await isClusterModel();
    const {
      strategy,
      checkedTemplate,
      selectedOnedays,
      selectedOnedaysError,
      onedays,
      timing: timeRange,
      ignoreType,
      startAt,
      endAt,
      customIgnoreTarget,
      errorMsg,
      priority,
      scanNodes
    } = this.state;
    const { onClose, sites, siteQuery } = this.props;

    if (selectedOnedaysError) {
      return;
    }
    if (errorMsg) {
      message.warning(errorMsg);
      return;
    }
    const params = { target: {}, oneday: {} };
    let targetDesc = '',
      onedayDesc = '';
    // 如果是集群 node默认为auto interface_type默认为'work'
    if (isCluster) {
      params.node = scanNodes;

      params.interface_type = 'work';
    } else {
      params.node = 'local';
    }
    // 单个下发
    if (!_.isEmpty(sites)) {
      params.target = { siteIdList: _.map(sites, '_id'), queryType: 'siteIdList' };
      const headSiteDesc = [sites[0].name, sites[0].ip, sites[0].ipv6, sites[0].url]
        .filter(Boolean)
        .join('|');
      targetDesc = `${headSiteDesc}${sites.length > 1 ? `等${sites.length}条资产` : ''}`;
    }
    // 全部下发 有疑似漏洞资产
    else if (siteQuery) {
      params.target = { queryType: 'hasSuspectVulSite' };
      targetDesc = siteQuery.description;
    }

    if (strategy === 'template') {
      const { key: templateId, label: templateName } = checkedTemplate;
      params.oneday = { templateId, queryType: 'template' };
      onedayDesc = templateName;
    } else if (strategy === 'custom') {
      params.oneday = { onedayDetailOids: selectedOnedays, queryType: 'list' };
      const haedOneday = _.find(onedays, oneday => selectedOnedays.includes(oneday._id));
      onedayDesc = `${_.get(haedOneday, ['name'])}${
        selectedOnedays.length > 1 ? `等${selectedOnedays.length}条漏洞` : ''
      }`;
    }
    // 受影响插件
    else if (strategy === 'affected') {
      onedayDesc = '受影响的插件';
      params.oneday.queryType = 'affectedByTarget';
    }
    if (
      _.isEmpty(params.oneday.onedayDetailOids) &&
      !params.oneday.affectedByTarget &&
      strategy !== 'affected' &&
      !params.oneday.templateId
    ) {
      return this.setState({ selectedOnedaysError: '请选择检测策略' });
    }

    params.name = `${targetDesc}_${onedayDesc}_${moment().format('YYYYMMDDHHmmss')}`;

    let newIgnoreType = [];
    if (ignoreType.whitelist) {
      newIgnoreType.push('whiteList');
    }
    if (ignoreType.custom) {
      params.customIgnoreTarget = customIgnoreTarget;
      if (!customIgnoreTarget.length) {
        message.warning('勾选了自定义忽悠目标，没有填写对应目标');
        return;
      }
      newIgnoreType.push('custom');
    }
    if (newIgnoreType.length) {
      params.ignoreType = newIgnoreType;
    }

    let timing = _.cloneDeep(timeRange);
    if (timing) {
      startAt && (timing.startAt = startAt.format('YYYY-MM-DD HH:mm:ss'));
      endAt && (timing.endAt = endAt.format('YYYY-MM-DD HH:mm:ss'));
      if (timing.dailyStart) {
        timing.dailyStart = timing.dailyStart.format('HH:mm');
      } else {
        delete timing.dailyStart;
      }
      if (timing.dailyEnd) {
        timing.dailyEnd = timing.dailyEnd.format('HH:mm');
      } else {
        delete timing.dailyEnd;
      }
      params.timing = timing;
    }

    if (priority) {
      params.priority = priority;
    }
    addOneday({ fields: params })
      .then(() => {
        this.setState({ ...this.defaultState });
        message.success('下发检测成功');
      }, onClose())
      .catch(({ type, message: messageString }) => {
        if (type === 'parsed') {
          message.error(messageString);
        } else {
          message.error('下发检测失败');
        }
      });
  };

  onCancel = () => {
    const { onClose } = this.props;
    this.setState({ ...this.defaultState }, onClose);
  };

  onCommonFieldChange = commonFields => {
    const fields = _.pick(commonFields, [
      'startAt',
      'endAt',
      'timing',
      'errorMsg',
      'priority',
      'ignoreType',
      'customIgnoreTarget',
      'scanNodes'
    ]);
    this.setState({ ...fields });
  };

  render() {
    const { visible, sites, targetCount, siteQuery } = this.props;
    const { strategy, selectedOnedaysError } = this.state;
    return (
      <Modal
        maskClosable={false}
        className={`${prefixCls}-modal`}
        title="1DAY检测"
        visible={visible}
        onCancel={this.onCancel}
        onOk={this.onSubmit}
        destroyOnClose
        width={570}
        okButtonProps={{ className: 'button-forwards' }}
      >
        <div className={`${prefixCls}-number`}>
          此次检测资产数
          <span>{targetCount}个</span>
        </div>
        <div className={`${prefixCls}-item`}>
          <div className={`${prefixCls}-item-sub-title`}>检测目标</div>
          <div className={`${prefixCls}-item-sites`}>
            {!_.isEmpty(sites) ? (
              _.map(sites, item => {
                const ip = _.get(item, 'ip', '');
                const ipv6 = _.get(item, 'ipv6', '');
                const url = _.get(item, 'url', '');
                return (
                  <Tooltip title={url ? `${ip || ipv6}(${url})` : ip || ipv6} key={name}>
                    <div className="site-tag">{url ? `${ip || ipv6}(${url})` : ip || ipv6}</div>
                  </Tooltip>
                );
              })
            ) : siteQuery ? (
              <Tooltip title={siteQuery.description}>
                <div className="site-tag">{siteQuery.description}</div>
              </Tooltip>
            ) : null}
          </div>
        </div>
        <div className={`${prefixCls}-item`}>
          <div className={`${prefixCls}-item-sub-title`}>检测策略</div>
          <div className={`${prefixCls}-item-template`}>
            <div className={`${prefixCls}-item-template-radio`}>
              <RadioGroup value={strategy} onChange={this.onStrategyChange}>
                <Radio value="affected">受影响插件</Radio>
              </RadioGroup>
            </div>
            {selectedOnedaysError && (
              <p className={`${prefixCls}-item-template-validate-error`}>{selectedOnedaysError}</p>
            )}
          </div>
        </div>
        <TaskCommonFields onCommonFieldChange={this.onCommonFieldChange} prefixCls={prefixCls} />
      </Modal>
    );
  }
}

CustomOnedayModal.propTypes = {
  visible: PropTypes.bool,
  onClose: PropTypes.func,
  sites: PropTypes.array,
  targetCount: PropTypes.number,
  siteQuery: PropTypes.array,
  strategy: PropTypes.string,
  history: PropTypes.object,
  isCluster: PropTypes.object
};

const mapStateToProps = state => {
  return {
    isCluster: _.get(state, 'auth.cert.is_cluster', false)
  };
};

export default connect(mapStateToProps)(CustomOnedayModal);
